package com.netbetter.langzheng.commons.gears.utils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.gears.client.database.Database;
import com.google.gwt.gears.client.database.DatabaseException;
import com.google.gwt.gears.client.database.ResultSet;
import com.google.gwt.json.client.JSONObject;
import com.netbetter.langzheng.commons.gears.dto.ParametersDTO;
import com.netbetter.langzheng.commons.gears.dto.SqlStateDTO;

public class GearsUtils {

  /**
   * 判断本地是否安装gears
   * 
   * @return
   */
  public static native boolean isGearsInstalled() /*-{
         try {
         return $wnd.google.gears.factory != null;
         } catch (e) {
         return false;
         }
         }-*/;

  private static String[] getValusByParameterDTO(ParametersDTO dto) {
    if (dto.getParameterMap() != null) {
      String[] values = new String[dto.getParameterMap().keySet().size()];
      Iterator<String> iter = dto.getParameterMap().keySet().iterator();
      int index = 0;
      while (iter.hasNext()) {
        String key = iter.next();
        if (!StringUtils.isEmpty(key)) {
          values[index] = dto.getParameterMap().get(key);
          index++;
        }
      }
      return values;
    }
    return new String[] {};
  }

  private static void supplementConditonByParameterDTO(StringBuffer buffer,
      ParametersDTO dto) {
    if (dto.getParameterMap() == null)
      return;
    Iterator<String> iter = dto.getParameterMap().keySet().iterator();
    while (iter.hasNext()) {
      String key = iter.next();
      if (!StringUtils.isEmpty(key)) {
        buffer.append(" and ").append(key).append("=?");
      }
    }
  }

  /**
   * 根据parameterDTO获得select count的sql语句
   * 
   * @param dto
   * @return
   */
  public static SqlStateDTO getSelectCountByParameterDTO(ParametersDTO dto) {
    StringBuffer buffer = new StringBuffer();
    buffer.append("select count(*) from ").append(dto.getLocalTableName()).append(
        " where 1=1");
    supplementConditonByParameterDTO(buffer, dto);
    SqlStateDTO retVal = new SqlStateDTO();
    retVal.setSql(buffer.toString());
    retVal.setValues(getValusByParameterDTO(dto));
    return retVal;
  }

  /**
   * 根据parameterDTO获得select * 的sql语句
   * 
   * @param dto
   * @return
   */
  public static SqlStateDTO getSelectByParameterDTO(ParametersDTO dto) {
    StringBuffer buffer = new StringBuffer();
    buffer.append("select * from ").append(dto.getLocalTableName()).append(
        " where 1=1");
    supplementConditonByParameterDTO(buffer, dto);
    SqlStateDTO retVal = new SqlStateDTO();
    retVal.setSql(buffer.toString());
    retVal.setValues(getValusByParameterDTO(dto));
    return retVal;
  }

  /**
   * 根据tableName与jsonObject获得create table sql
   * 
   * @param tableName
   * @param jsonObject
   * @return
   */
  public static SqlStateDTO getCreateSqlByJSONObject(String tableName,
      JSONObject jsonObject) {
    SqlStateDTO retVal = new SqlStateDTO();
    Iterator<String> keyIter = jsonObject.keySet().iterator();
    StringBuffer buffer = new StringBuffer("create table if not exists "
        + tableName + " (");
    while (keyIter.hasNext()) {
      String key = keyIter.next();
      buffer.append(key).append(" varchar(255),");
    }
    buffer.append("gmt_create varchar(255),gmt_modified varchar(255))");
    retVal.setSql(buffer.toString());
    return retVal;
  }

  /**
   * 根据tableName与jsonObject获得insert table sql
   * 
   * @param tableName
   * @param jsonObject
   * @return
   */
  public static SqlStateDTO getInsertSqlByJSONObject(String tableName,
      JSONObject jsonObject) {
    SqlStateDTO retVal = new SqlStateDTO();
    StringBuffer buffer = new StringBuffer("insert into " + tableName
        + " values(");
    int size = jsonObject.keySet().size();
    for (int i = 0; i < size; i++) {
      buffer.append("?,");
    }
    buffer.append("?,?)");
    String[] values = new String[jsonObject.keySet().size() + 2];
    int index = 0;
    Iterator<String> keyIter = jsonObject.keySet().iterator();
    while (keyIter.hasNext()) {
      String key = keyIter.next();
      values[index] = jsonObject.get(key).toString();
      index++;
    }
    values[index] = new Date().getTime() + "";
    index++;
    values[index] = new Date().getTime() + "";
    retVal.setSql(buffer.toString());
    retVal.setValues(values);
    return retVal;
  }

  public static int getCountForSql(Database localDB, SqlStateDTO sqlDto)
      throws DatabaseException {
    int result = 0;
    ResultSet rs = localDB.execute(sqlDto.getSql(), sqlDto.getValues());
    try {
      for (int i = 0; rs.isValidRow(); ++i, rs.next()) {
        result = rs.getFieldAsInt(0);
      }
    } catch (DatabaseException error) {
      throw error;
    } finally {
      rs.close();
    }
    return result;
  }

  public static List<Map<String, String>> getListForSql(Database localDB,
      SqlStateDTO sqlDto) throws DatabaseException {
    List<Map<String, String>> retVal = new ArrayList<Map<String, String>>();
    ResultSet rs = localDB.execute(sqlDto.getSql(), sqlDto.getValues());
    try {
      for (int i = 0; rs.isValidRow(); ++i, rs.next()) {
        Map<String, String> item = new HashMap<String, String>();
        int fieldCount = rs.getFieldCount();
        for (int j = 0; j < fieldCount; j++) {
          String key = rs.getFieldName(j);
          String value = rs.getFieldAsString(j);
          if ("\"\"".equals(value)) {
            value = "";
          }
          if (value.length() > 2) {
            if (value.charAt(0) == '\"'
                && value.charAt(value.length() - 1) == '\"') {
              value = value.substring(1, value.length() - 1);
            }
          }
          item.put(key, value);
        }
        retVal.add(item);
        if (Log.isDebugEnabled()) {
          StringBuffer logInfo = new StringBuffer("sql:" + sqlDto.getSql()
              + " value ");
          Iterator<String> iter = item.keySet().iterator();
          while (iter.hasNext()) {
            String key = iter.next();
            logInfo.append(key).append("=").append(item.get(key)).append(" ");
          }
          Log.debug(logInfo.toString());
        }
      }
    } catch (DatabaseException error) {
      throw error;
    } finally {
      rs.close();
    }
    return retVal;
  }
}
